<template>
    <div class="upload-window card" v-if="list.length">
        <div v-if="!visible" @click="_onShowDialog" style="cursor: pointer;" class="flex-between">
            正在上传的列表
            <div style="color:gray;font-size:10px">{{ list.length }}条</div>
        </div>
        <el-dialog v-else custom-class="upload-dialog" :modal-append-to-body="true" :modal="false" :lock-scroll='false' :show-close='true' :center="true" :close-on-press-escape='false' :close-on-click-modal='false' :visible.sync="visible" width="450px" @close="_onDialogClosed">
            <div slot="title" class="header">上传列表</div>
            <div class="h-100 body">
                <div v-for="(item) in list" :key='item.id' class="h-100 w-100">
                    <upload-list-item class="card" style="margin-bottom:10px;" :name="item.fileName" :size="item.fileSize" :status="item.status" :progress="Math.floor(item.progress * 100)" @on-delete-click="_onDeletedClick(item)"></upload-list-item>
                </div>
            </div>
        </el-dialog>
    </div>
</template>
<script>
import UploadListItem from './upload-list-item';
import { mapMutations, mapState } from 'vuex';
import $http from '@http';
/**
 * 上传列表
 * @Author lixingyan [2022-02-24 11:01:57]
 * @Description 
 * 
 */
export default {
    name: 'upload-list-dialog',
    components: {
        [UploadListItem.name]: UploadListItem
    },
    props: {},
    watch: {
        upload: {
            handler(value) {
                let { visible, list, uploadItem } = value || {}
                this.visible = visible
                this.list = (list || []).map(item => {
                    if (item.id == (uploadItem || {}).id) return uploadItem
                    return item
                })
            }, immediate: true, deep: true
        },
        fileListing: {
            handler() {
                if (JSON.stringify(this.filing) == "{}" && this.fileListing.length > 0) {
                    window.removeEventListener('beforeunload', this.beforeunloadFn)
                    window.addEventListener('beforeunload', this.beforeunloadFn)
                    this.Filing()
                    let { list } = this.$upload.read(this.userNumber) || {}
                    //上传文件
                    if (list && list.length > 0) {
                        list = list.map(item => {
                            if (item.id == this.filing.filedata.id) {
                                item = this.filing.filedata
                            } else {
                                item.callback = (id) => {
                                    this.FILESTING_FILTER(id)
                                }
                            }
                            return item
                        })
                        this.$store.commit('upload', { visible: true, list: list })
                        this.$upload.write(this.userNumber, { visible: true, list: list })
                    }
                    this.toUploade()
                } else if (JSON.stringify(this.filing) == "{}" && this.fileListing.length == 0) {
                    window.removeEventListener('beforeunload', this.beforeunloadFn)
                } else {
                    return
                }
            }, immediate: true, deep: true
        },
    },
    data() {
        return {
            visible: false,
            list: [],
            number: (this.$user.read() || {}).number,
            // ------镜像上传
            //文件队列
            // fileListing: [],
            piece: 2 * 1024 * 1024,
            //正在上传的文件
            // filing: {},
            isSubmit: false,
            paramsData: {},
            fileData: {},
            userNumber: '',
        }
    },
    created() {
        // 组件生成的时候删除之前的数据
        this.$upload.delete(this.number)
        this.userNumber = (this.$user.read() || {}).number;
    },

    computed: {
        // ...mapState('image', ["fileListing", "filing"])
        ...mapState({
            filing: state => state['image-upload-store'].filing,
            fileListing: state => state['image-upload-store'].fileListing,
            upload: state => state['image-upload-store'].upload
        })
    },
    methods: {
        /**
         * 页面刷新监听
         */
        beforeunloadFn(event) {
            if (event) {
                event.returnValue = '关闭提示';
            }
            return this.$upload.delete(this.userNumber)
        },

        /**
         * 关闭弹窗
         */
        _onDialogClosed() {
            this.visible = false
            this.$upload.write(this.number, { visible: false, list: this.list })
        },

        /**
         * 展开弹窗
         */
        _onShowDialog() {
            this.visible = true
            this.$upload.write(this.number, { visible: true, list: this.list })
        },

        /**
         * 删除
         */
        _onDeletedClick(item) {
            if (item.status == 'waiting') {
                item.callback && item.callback(item.id)
                const index = this.list.findIndex(list => list.id == item.id)
                this.list.splice(index, 1)
                this.$upload.write(this.number, { visible: true, list: this.list })
            } else if (item.status == 'success' || item.status == 'error' || item.status == 'cancel') {
                const index = this.list.findIndex(list => list.id == item.id)
                this.list.splice(index, 1)
                this.$upload.write(this.number, { visible: true, list: this.list })
                this.$store.commit('upload', { visible: true, list: this.list })
                if (this.list.length === 0) {
                    this.$upload.delete(this.number)
                    this.$store.commit('upload', { visible: true, list: this.list })
                }
                return
            } else {
                item.status = 'cancel'
                this.$notify.success('已取消上传')
            }
            // this.$store.commit('upload', { visible: true, list: this.list, isCancel: true, currentItem: item })
        },

        /**
         * -----------------------------------------------------------------------------------------------------
         * 以下都是镜像上传方法
         */

        /**
         * FILESTING_PUSH() 		添加文件到上传队列
         * FILESTING_FILTER()		取消、删除上传的文件
         * FILESTING_SHIFT()		删除上传完成的上传队列
         * Filing()					正在上传的文件
         */
        ...mapMutations('image-upload-store', ["FILESTING_PUSH", "FILESTING_FILTER", 'FILESTING_SHIFT', "Filing", "Filing_NULL"]),

        // 调用上传，设置参数
        toUploade() {
            // const { file, params, filedata } = this.filing;
            //列表展示
            this.fileData = this.filing.filedata
            //镜像参数
            this.paramsData = this.filing.params
            const url = `/file/temp`;
            // this._addFileShow(this.fileData, 'up')
            // 上传检测 续传
            $http.get(url, this.fileData).then(uploaded => {
                const uploades = uploaded || 0;
                this.uploading(this.filing.file, uploades);
            })
        },

        /**
         * 删除队列中未上传的文件
         */
        async uploading(file, uploaded) {
            const { size } = file
            let start = uploaded;
            //取最小值
            let end = Math.min(uploaded + this.piece, size);
            //截取二进制文件
            let target = file.slice(start, end);
            // 将参数写入data
            let data = Object.assign({}, this.fileData, this.paramsData, {
                startSize: start,
                file: target
            })
            // 转换为二进制文件
            const form = new FormData();
            Object.keys(data).forEach(key => {
                form.append(key, data[key]);
            });
            const result = await $http.post('libAdmin/image', form, { 'Content-Type': 'multipart/form-data' })
            let { startSize, schedule } = result;
            this.fileData.progress = startSize / size
            // 取消上传
            if (this.fileData.status == 'cancel') {
                await $http.delete(`file/temp`, this.fileData)
                this.fileData.status = 'cancel'
                let { list } = this.$upload.read(this.userNumber) || {}
                list = list.map(item => {
                    if (item.id == this.fileData.id) {
                        item = this.fileData
                    } else {
                        item.callback = (id) => {
                            this.FILESTING_FILTER(id)
                        }
                    }
                    return item
                })
                this.$store.commit('upload', { visible: true, list: list })
                this.$upload.write(this.userNumber, { visible: true, list: list })
                this.FILESTING_SHIFT()
                this.fileData = {}
                this.Filing_NULL()
                return
            }
            // 上传成功
            else if (schedule == '100%') {
                this.$notify.success("上传成功")
                console.log("上传成功");
                this.fileData.status = 'success'
                // 将上传成功的this.fileData 覆盖list中的
                let { list } = this.$upload.read(this.userNumber) || {}
                console.log(this.fileData, 'this.fileData', list, 'list');
                if (list) {
                    list = list.map(item => {
                        if (item.id == this.fileData.id) {
                            item = this.fileData
                        } else {
                            item.callback = (id) => {
                                this.FILESTING_FILTER(id)
                            }
                        }
                        return item
                    })
                }
                this.$store.commit('upload', { visible: true, list: list })
                this.$upload.write(this.userNumber, { visible: true, list: list })
                this.FILESTING_SHIFT()
                this.Filing_NULL()
                return
            } else {
                // 设置状态为上传中
                this.fileData.status = 'uploading'
                // 回调
                this.uploading(file, startSize)
            }
        },

        _addFileShow(info, staus) {
            let { list } = this.$upload.read(this.userNumber) || {}
            //上传文件
            if (list && list.length > 0 && staus == 'up') {
                list = list.map(item => {
                    if (item.id == this.fileData.id) {
                        item = this.fileData

                    } else {
                        item.callback = (id) => {
                            this.FILESTING_FILTER(id)
                        }
                    }
                    return item
                })
                this.$store.commit('upload', { visible: true, list: list })
                this.$upload.write(this.userNumber, { visible: true, list: list })
            }
        }
    }
}
</script>
<style lang="scss" scoped>
.upload-window {
    position: absolute !important;
    right: 10px;
    bottom: 10px;
    width: 450px;

    // max-height: 200px;
    padding: 10px;
    box-sizing: content-box;
    background: white;
    /deep/.el-dialog__wrapper {
        position: relative;
        .upload-dialog {
            margin-top: 0 !important;
            margin-bottom: 0 !important;
            .el-dialog__header {
                padding: 0px !important;
                height: 30px !important;
                // border: none;
            }
            .el-dialog__headerbtn {
                top: 0px !important;
                right: 3px !important;
            }
            .el-dialog__body {
                padding: 0px;
                border: none;
                max-height: 150px;
                overflow: auto;
            }
        }
        /deep/.v-modal {
            position: relative !important;
        }
    }
}
</style>